package player;

import adventure.Adventure;
import adventure.AdventureEdit;
import adventure.vocation.Vocation;
import adventure.vocation.VocationManager;
import adventure.vocation.VocationManagerImp;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import parser.PlayerParse;

/**
 *
 * @author Michael Hanns
 *
 */
public class PlayerManagerImp implements PlayerManager {

    private VocationManager vocations;
    private ArrayList<Player> playersOnline;
    private ArrayList<Player> playersOffline;
    private int totalPlayers;
    private String pathFolder;
    private int sx;
    private int sy;
    private int sz;
    private Adventure adv;

    public PlayerManagerImp(String folderpath, Adventure a) {
        playersOnline = new ArrayList<Player>();
        playersOffline = new ArrayList<Player>();
        vocations = new VocationManagerImp();
        totalPlayers = 0;
        this.pathFolder = folderpath;
        this.adv = a;

        sx = 1;
        sy = 1;
        sz = 1;

        if (pathFolder != null) {
            File path = new File((pathFolder + "1.witpl"));
            System.out.println(path.getAbsolutePath());

            if (path.isFile()) {
                readPlayers();
            } else {
                createAdmin();
            }
        }
    }

    @Override
    public void setStartArea(int x, int y, int z) {
        sx = x;
        sy = y;
        sz = z;
    }

    @Override
    public void setVocationManager(VocationManager vocs) {
        this.vocations = vocs;
    }

    private void readPlayers() {
        int x = 1;
        File tempFile = new File(pathFolder + "1.witpl");
        PlayerParse parser = new PlayerParse(adv, this, ((AdventureEdit) adv).getBroadcaster());

        while (tempFile.isFile()) {
            // Read the data
            parser.readPlayerFile(tempFile);

            // Add to offline players
            playersOffline.add((Player) parser.getPlayer());
            totalPlayers++;

            // Increment to next file
            parser = new PlayerParse(adv, this, ((AdventureEdit) adv).getBroadcaster());
            x++;
            tempFile = new File(pathFolder + x + ".witpl");
        }
    }

    private void createAdmin() {
        try {
            File path = new File(pathFolder);
            System.out.println("Path: " + path.getAbsolutePath());
            if (!path.isDirectory()) {
                boolean makeDir = path.mkdirs();
                if (!makeDir) {
                    System.out.println("Directory not created! Making character in local folder...");
                    pathFolder = "";
                }
            }
            File pathFolderF = new File(pathFolder + "1.witpl");
            PrintStream writer = new PrintStream(new FileOutputStream(pathFolderF));

            PlayerEdit admin = new PlayerImp(1);
            admin.setCurrencyType(adv.getCurrency());
            admin.setName("Admin");
            admin.setPassword("password");
            admin.setSpawnX(sx);
            admin.setSpawnY(sy);
            admin.setSpawnZ(sz);
            admin.setX(sx);
            admin.setY(sy);
            admin.setZ(sz);
            admin.setSuperAdmin(true);

            // Parse the player into the right language
            PlayerParse parser = new PlayerParse(adv, this, ((AdventureEdit) adv).getBroadcaster());
            writer.println(parser.convertToXML((Player) admin));
            writer.close();

            playersOffline.add((Player) admin);
            totalPlayers++;

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean createPlayer(String name, String password, Vocation voc) {
        if (totalPlayers > 0) {
            try {
                File path = new File(pathFolder);
                System.out.println("Path: " + path.getAbsolutePath());
                if (!path.isDirectory()) {
                    boolean makeDir = path.mkdirs();
                    if (!makeDir) {
                        System.out.println("Directory not created! Making character in local folder...");
                        pathFolder = "";
                    }
                }
                File pathFolderF = new File(pathFolder + (totalPlayers + 1) + ".witpl");

                if (pathFolderF.createNewFile()) {
                    PrintStream writer = new PrintStream(new FileOutputStream(pathFolderF));

                    PlayerEdit newPlayer = new PlayerImp(totalPlayers + 1);
                    System.out.println("New Player added - currency: " + adv.getCurrency().getStatusID());
                    newPlayer.setCurrencyType(adv.getCurrency());
                    newPlayer.setName(name);
                    newPlayer.setPassword(password);
                    newPlayer.setSpawnX(sx);
                    newPlayer.setSpawnY(sy);
                    newPlayer.setSpawnZ(sz);
                    newPlayer.setX(sx);
                    newPlayer.setY(sy);
                    newPlayer.setZ(sz);
                    newPlayer.setVocation(voc);

                    // Parse the player into the right language
                    PlayerParse parser = new PlayerParse(adv, this, ((AdventureEdit) adv).getBroadcaster());
                    writer.println(parser.convertToXML((Player) newPlayer));
                    writer.close();

                    playersOffline.add((Player) newPlayer);
                    totalPlayers++;
                    return true;
                } else {
                    System.out.println("ERROR: Player file not created!");
                    return false;
                }

            } catch (IOException e) {
                e.printStackTrace();

                return false;
            }
        } else {
            createAdmin();
            createPlayer(name, password, voc);
        }
        return false;
    }

    @Override
    public boolean savePlayers() {
        try {
            PrintStream writer;
            File pathFolderF;
            PlayerParse parser;
            for (int x = 0; x < playersOnline.size(); x++) {
                pathFolderF = new File(pathFolder + playersOnline.get(x).getID() + ".witpl");
                if (pathFolderF.createNewFile()) {
                    writer = new PrintStream(new FileOutputStream(pathFolderF));

                    // Parse the player into the right language
                    parser = new PlayerParse(adv, this, ((AdventureEdit) adv).getBroadcaster());
                    writer.println(parser.convertToXML(playersOnline.get(x)));
                    writer.close();
                } else {
                    writer = new PrintStream(new FileOutputStream(pathFolderF));

                    // Parse the player into the right language
                    parser = new PlayerParse(adv, this, ((AdventureEdit) adv).getBroadcaster());
                    writer.println(parser.convertToXML(playersOnline.get(x)));
                    writer.close();
                    return false;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return true;
    }

    private boolean savePlayer(int id) {
        try {
            PrintStream writer;
            File pathFolderF;
            PlayerParse parser;
            boolean found = false;
            for (int x = 0; x < playersOnline.size() && !found; x++) {
                if (playersOnline.get(x).getID() == id) {
                    found = true;
                    pathFolderF = new File(pathFolder + playersOnline.get(x).getID() + ".witpl");
                    if (pathFolderF.createNewFile()) {
                        writer = new PrintStream(new FileOutputStream(pathFolderF));

                        // Parse the player into the right language
                        parser = new PlayerParse(adv, this, ((AdventureEdit) adv).getBroadcaster());
                        writer.println(parser.convertToXML(playersOnline.get(x)));
                        writer.close();

                        return true;
                    } else {
                        writer = new PrintStream(new FileOutputStream(pathFolderF));

                        // Parse the player into the right language
                        parser = new PlayerParse(adv, this, ((AdventureEdit) adv).getBroadcaster());
                        writer.println(parser.convertToXML(playersOnline.get(x)));
                        writer.close();
                        return false;
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean logOn(String name, String password) {
        boolean found = false;
        for (int x = 0; x < playersOffline.size() && !found; x++) {
            if (playersOffline.get(x).loginCorrect(name, password)) {
                playersOnline.add(playersOffline.get(x));
                playersOffline.remove(x);
                found = true;
            }
        }
        return found;
    }

    @Override
    public boolean logOff(int id) {
        boolean found = false;
        for (int x = 0; x < playersOnline.size() && !found; x++) {
            if (playersOnline.get(x).getID() == id) {
                savePlayer(playersOnline.get(x).getID());

                playersOffline.add(playersOnline.get(x));
                playersOnline.remove(x);
                found = true;
            }
        }
        return found;
    }

    @Override
    public int onlinePlayers() {
        return playersOnline.size();
    }

    @Override
    public Player getOfflinePlayer(String name) {
        for (int x = 0; x < playersOffline.size(); x++) {
            if (playersOffline.get(x).getAliveName().equalsIgnoreCase(name)) {
                return playersOffline.get(x);
            }
        }

        Player noShow = new PlayerImp();
        return noShow;
    }

    @Override
    public Player getOnlinePlayer(String name) {
        for (int x = 0; x < playersOnline.size(); x++) {
            if (playersOnline.get(x).getAliveName().equalsIgnoreCase(name)) {
                return playersOnline.get(x);
            }
        }

        Player noShow = new PlayerImp();
        return noShow;
    }

    @Override
    public Player getOnlinePlayer(int id) {
        for (int x = 0; x < playersOnline.size(); x++) {
            if (playersOnline.get(x).getID() == id) {
                return playersOnline.get(x);
            }
        }

        Player noShow = new PlayerImp();
        return noShow;
    }

    @Override
    public Player getOnlinePlayerAtIndex(int index) {
        if (index < playersOnline.size()) {
            return playersOnline.get(index);
        }
        Player noShow = new PlayerImp();
        return noShow;
    }

    @Override
    public String[] getVocationNames() {
        String[] vocs = new String[vocations.totalVocations()];

        int x = 1;
        while (vocations.getVocation(x).getID() != 0) {
            vocs[x - 1] = vocations.getVocation(x).getName();
            x++;
        }
        return vocs;
    }

    @Override
    public Vocation getVocation(int x) {
        return vocations.getVocation(x);
    }
}
